refactor: route all markdown parsing through mdq() (plan 022)#93
Merged
Conversation
Enforce the "no regex/includes/line-splitting on markdown" rule across 8
violation sites. Adds one additive accessor — MarkdownQuery.meta() returning
{type, depth, text} — which removes the need for hand-rolled marked.lexer
walks. The `marked` import is now gone from experience-tracker and
experience-compactor.
- researcher Summary regex + parser `.includes('Extended Research')` -> mdq queries
- planner cleanExperienceFlows + table swap -> positional replaces with
re-query-after-each-mutation (no more String.replace on section raw text /
/^---/gm regex)
- experience-tracker: whole-section truncation (never cuts mid-fence),
writeAction/writeFlow dedup via mdq, listTocHeadings/extractHeadingSection/
renderAsHowTo rebuilt on meta()
- experience-compactor: listSections on mdq; clickXY regex -> isNonReusableCode
- knowledge-tracker firstLine via mdq().meta()
Deviations (both improvements, verified): renderAsHowTo matches with startsWith
via meta() (the plan's contains-matcher would infinite-loop on titles
containing the marker); planner's "and N more discoveries" note-append was
previously dead code (no-op after the tail blockquotes were removed) and now
correctly appends. Step 5 verified byte-identical to the old lexer walk;
Step 7's clickXY->isNonReusableCode broadening pinned by no test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Explorbot Self-RegressionCommit
Attempt details
Session analysis — basic (native): Session AnalysisThe issues list feature was explored across 5 test scenarios covering creation, search, filtering by status and label, and detail navigation. All core flows work correctly. The standout observation is that two tests required multiple click attempts to succeed, suggesting automation reliability concerns rather than product defects. Coverage
What works
Execution Issues
|
DenysKuchma
approved these changes
Jul 13, 2026
DavertMik
commented
Jul 15, 2026
| for (const bq of blockquotes.slice(10)) { | ||
| result = result.replace(bq.text(), ''); | ||
| const trimmedTitles = new Set<string>(); | ||
| while (true) { |
Contributor
Author
There was a problem hiding this comment.
do not do while true!!!!
seems like we should simplify it
DavertMik
commented
Jul 15, 2026
| { marker: 'FLOW:', suffix: 'multi-step' }, | ||
| { marker: 'ACTION:', suffix: 'single-step' }, | ||
| ]) { | ||
| while (true) { |
Contributor
Author
There was a problem hiding this comment.
model keeps doing while(true)
i think we can move this iterator to the mdq
like
mdq(result).forEach('h2', ...)
DavertMik
commented
Jul 15, 2026
DavertMik
left a comment
Contributor
Author
There was a problem hiding this comment.
Idea is good but while true must be avoided
it doesn't simplify things!
DavertMik
added a commit
that referenced
this pull request
Jul 15, 2026
Only the items in files untouched by the other open refactor PRs, so this
does not conflict with them:
- fisherman-tools: `value === null || value === undefined` -> `value == null`
(0/''/false are valid field values, so not `!value`)
- quartermaster: move the 4 interfaces to end of file; outputPath('a11y')
instead of join(getOutputDir(), 'a11y'); drop the existsSync guard
(mkdirSync recursive tolerates existing) and inline ensureDirectory away.
The bulk of plan 016 (private-method reordering, type-moves, ternary and
conditional-spread cleanups across tester/tools/provider/pilot/etc.) is
DEFERRED: 016 is the run-last plan and pure-move reorderings conflict with
every open PR. It should run after #85-#93 land.
Co-authored-by: DavertMik <davert@testomat.io>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…efactor/mdq-compliance
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Plan 022 — Route all markdown manipulation through
mdq()The project rule (CLAUDE.md, twice) is absolute: all markdown manipulation goes through
mdq()— never regex,.includes(), or line-splitting. This fixes 8 violations, including 4 hand-rolledmarked.lexerwalks that re-implemented mdq's own section logic with subtly different semantics.New mdq API (additive only)
MarkdownQuery.meta()→Array<{type, depth, text}>— exposes token type, heading depth, and unwrapped text. This is the gap that forced the lexer walks. 6 new unit cases inmarkdown-query.test.ts.Migrated
researcher.ts## Summaryregex +researcher/parser.ts.includes('Extended Research')→ mdq queries.planner.tscleanExperienceFlows+ table swap → positional.replace()with re-query-after-each-mutation (offsets go stale after a replace). Removed allString.replace(section.text(), …)and/^---/gm.experience-tracker.ts: whole-section truncation (never cuts mid-code-fence),writeAction/writeFlowdedup via mdq, andlistTocHeadings/extractHeadingSection/renderAsHowTorebuilt onmeta().experience-compactor.ts:listSectionsonsection2+meta(); the re-hardcoded clickXY regex →isNonReusableCode().knowledge-tracker.tsfirstLine →mdq().meta().markedimport removed from experience-tracker and experience-compactor.Two deviations (both improvements, verified)
renderAsHowTousesstartsWithviameta(), not the plan's literalh2(~"marker"). That contains-matcher would infinite-loop on a title containing the marker (## FLOW: undo FLOW: steps) and diverges from the oldstartsWith. The implemented version provably terminates and matches the old output (whitespace-only diff — the old code accidentally doubled blank lines).cleanExperienceFlows'> ... and N more discoveriesnote was dead code — the old.replace()no-op'd because the tail blockquotes were already removed from the string. The new code correctly appends it, as the plan specifies.STOP-candidates cleared
isNonReusableCodebroadening — no test pins the narrow behavior; the#ember123case yields the same final result (dropped at strip stage). All 43 compactor tests pass.Verification
bun test tests/unit→ 772 pass / 0 fail (+8 new tests; no existing assertions modified).bun test tests/integration/→ 63 pass / 0 fail.bun run lint→ clean;tsctotal neutral (639 = 639).grep markedin both files → empty;## Summaryregex gone;meta()present.🤖 Generated with Claude Code